<?php

namespace App\Datalog;

use App\Models\WxMiniprogramConfig;
use Jenssegers\Agent\Facades\Agent;
use YQ\YqExtend;

class ErrorLog extends LaravelDatalogBase
{
    // 日志名称
    protected $name = 'error';

    // 请求日志单独存放
    protected $logPath = 'datalogs/error';

    protected $formatter = 'context';

    const ERROR_TYPE_CODE = 1001; // 程序异常
    const ERROR_TYPE_WX_MINIPROGRAM = 1002; // 小程序事件
    const ERROR_TYPE_WX_TEXT = 1003; // 小程序用户消息

    private function getTraceFile($trace_list = [])
    {
        $res = [];
        foreach ($trace_list as $trace_file) {
            if (!isset($trace_file['file'])) {
                continue;
            }

            // 只采集app目录下的文件信息
            if (strpos($trace_file['file'], '/app/') !== false) {
                $res[] = $trace_file['file'] . ':' . $trace_file['line'];
            }
        }

        return $res;
    }

    private function getRequestInfo()
    {
        $info = [
            'ip'         => YqExtend::getIP(),
            'url'        => request()->fullUrl(),
            'path'       => request()->path(),
            'method'     => request()->method(),
            'ua'         => Agent::getUserAgent(),
            'input_data' => '',
            'data'       => [],
        ];
        if ($info['method'] == 'POST') {
            $info['data'] = request()->input();
            if (empty($info['data'])) {
                $info['input_data'] = file_get_contents('php://input');
            }
        }

        return $info;
    }

    public function addThrowable($error)
    {
        $params = [
            'error_type'   => ErrorLog::ERROR_TYPE_CODE,
            'create_time'  => time(),
            'create_time2' => microtime(true),
            'date_time'    => date('Y-m-d H:i:s', time()),
            'class'        => get_class($error),
            'code'         => $error->getCode(),
            'file'         => $error->getFile(),
            'line'         => $error->getLine(),
            'msg'          => $error->getMessage(),
            'trace'        => $this->getTraceFile($error->getTrace()),
            'request_info' => $this->getRequestInfo(),
        ];

        $this->log($params);
    }

    // 小程序消息事件报警
    public function addWxMiniprogramWarning(WxMiniprogramConfig $program, array $params)
    {
        $msg = $params['rule_name'] ?? '';
        $log = [
            'error_type'   => ErrorLog::ERROR_TYPE_WX_MINIPROGRAM,
            'error_name'   => '小程序报警',
            'create_time'  => time(),
            'create_time2' => microtime(true),
            'date_time'    => date('Y-m-d H:i:s', time()),
            'msg'          => $msg,
            'request_info' => [
                'appid' => $program->appid,
                'name' => $program->name,
                'punish_time' => $params['punish_time'] ?? 0,
            ]
        ];

        $this->log($log);
    }

    // 小程序被封报警
    public function addWxMiniprogramLimit(WxMiniprogramConfig $program, $msg)
    {
        $log = [
            'error_type'   => ErrorLog::ERROR_TYPE_WX_MINIPROGRAM,
            'error_name'   => '小程序报警',
            'create_time'  => time(),
            'create_time2' => microtime(true),
            'date_time'    => date('Y-m-d H:i:s', time()),
            'msg'          => $msg,
            'request_info' => [
                'appid' => $program->appid,
                'name' => $program->name,
            ]
        ];

        $this->log($log);
    }

    // 小程序用户消息报警
    public function addWxMiniprogramText(WxMiniprogramConfig $program, array $params)
    {
        $msg         = $params['Content'] ?? '';
        $punish_time = $params['punish_time'] ?? 0;
        $image_url   = $params['PicUrl'] ?? '';
        $wx_openid   = $params['FromUserName'] ?? '';

        $log = [
            'error_type'   => ErrorLog::ERROR_TYPE_WX_TEXT,
            'error_name'   => '小程序用户消息',
            'create_time'  => time(),
            'create_time2' => microtime(true),
            'date_time'    => date('Y-m-d H:i:s', time()),
            'msg'          => $msg,
            'request_info' => [
                'appid'       => $program->appid,
                'name'        => $program->name,
                'punish_time' => $punish_time,
                'image_url'   => $image_url,
                'wx_openid'   => $wx_openid,
            ]
        ];

        $this->log($log);
    }
}
